package com.viknix.threadpool.manager.http;

import com.viknix.threadpool.manager.server.dependence.util.IPUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Author: Dongqi
 * @Date: 2021/11/22 10:57
 * @Version 1.0
 * @Description: A HostnameVerifier verify ipv4 and localhost.
 */
public final class SelfHostnameVerifier implements HostnameVerifier {

    private static final Logger LOGGER = LoggerFactory.getLogger(SelfHostnameVerifier.class);

    private final HostnameVerifier hv;

    private static ConcurrentHashMap<String, Boolean> hosts = new ConcurrentHashMap<String, Boolean>();

    private static final String[] LOCALHOST_HOSTNAME = new String[]{"localhost", IPUtil.localHostIP()};

    public SelfHostnameVerifier(HostnameVerifier hv) {
        this.hv = hv;
    }

    @Override
    public boolean verify(String hostname, SSLSession session) {
        if (LOCALHOST_HOSTNAME[0].equalsIgnoreCase(hostname) || LOCALHOST_HOSTNAME[1].equals(hostname)) {
            return true;
        }
        if (isIP(hostname)) {
            return true;
        }
        return hv.verify(hostname, session);
    }

    private static boolean isIP(String host) {
        if (host == null || host.isEmpty()) {
            LOGGER.warn("host is empty, isIP = false");
            return false;
        }
        Boolean cacheHostVerify = hosts.get(host);
        if (cacheHostVerify != null) {
            return cacheHostVerify;
        }
        boolean isIp = IPUtil.isIP(host);
        hosts.putIfAbsent(host, isIp);
        return isIp;
    }
}
